"""
本文件定义了多种经济合同和商品类，用于模拟经济数据可视化项目中的经济活动。
这些类涵盖了消费品、资本品、存款、贷款、就业、股份、债券等多种经济概念，
通过定义这些类，可以方便地创建和管理各种经济合同和商品信息。

主要包含以下类：
- ConsumptionGoods: 消费品类
- ConsumptionContract: 消费品供需合同类
- CapitalGoods: 资本品存货类
- CapitalContract: 资本品合同类
- DepositContract: 存款合同类
- TreasuryDepositContract: 财政（国库）存款合同类
- LoanContract: 贷款合同类
- LoanContractCollection: 贷款合同集合类
- JobContract: 劳动力合同类
- StockHolderContract: 股份归属合同类
- BondContract: 债券合约类
- CashAdvanceContract: 现金预借款合约类
- ReserveContract: 保证金合同类

每个类都有自己的属性和方法，部分类还实现了 __str__ 方法，用于提供格式化的字符串表示，方便打印和调试。
LoanContractCollection 类还实现了迭代器协议，允许对贷款合同进行迭代操作。
"""
import numpy as np

from typing import List

from utils import apt


class ConsumptionGoods:
    """
    消费品
    """

    def __init__(self, year, quantity, unit_cost, price):
        self.year = year
        self.quantity = quantity
        self.keep_quantity = quantity
        self.unit_cost = unit_cost
        self.price = price

    def __str__(self):
        str_ = '【消费品】'
        for attr, value in vars(self).items():
            if isinstance(value, float):
                str_ += f"-【{attr}:{value:.4f}】"
            else:
                str_ += f"-【{attr}:{value}】"
        return str_


class ConsumptionContract:
    """
    消费品供需合同
    """

    def __init__(self, contract):
        if len(contract) > 0:
            self.household_id = contract['household_id']
            self.c_firm_id = contract['c_firm_id']
            self.price = contract['price']
            self.quantity = contract['quantity']
            self.con_deposit = contract['con_deposit']
            self.income = contract['con_income']
            self.a1 = contract['a1']
            self.a2 = contract['a2']
            self.max_q = contract['max_q']

    def __str__(self):
        str_ = '【消费品合同】'
        for attr, value in vars(self).items():
            if isinstance(value, float):
                str_ += f"-【{attr}:{value:.4f}】"
            else:
                str_ += f"-【{attr}:{value}】"
        return str_


class CapitalGoods:
    """
    资本品存货
    """

    def __init__(self, year, quantity, price, share):
        self.year = year
        self.quantity = quantity
        self.keep_quantity = quantity
        self.share = share
        self.price = price

    def __str__(self):
        str_ = '【资本品】'
        for attr, value in vars(self).items():
            if isinstance(value, float):
                str_ += f"-【{attr}:{value:.4f}】"
            else:
                str_ += f"-【{attr}:{value}】"
        return str_


class CapitalContract:
    """
    资本品合同
    """

    def __init__(self, contract):
        if len(contract) > 0:
            self.c_firm_id = contract['c_firm_id']
            self.k_firm_id = contract['k_firm_id']
            self.price = contract['price']
            self.quantity = contract['quantity']

    def __str__(self):
        str_ = '【资本品合同】'
        for attr, value in vars(self).items():
            str_ += f"-【{attr}:{value}】"
        return str_


class DepositContract:
    """
    存款合同
    """

    def __init__(self, contract):
        if len(contract) > 0:
            self.bank_id = contract['bank_id']
            self.amount = contract['amount']
            self.interest_rate = contract['interest_rate']
            self.depositor = contract['depositor']  # 谁存的？

    def __str__(self):
        str_ = ''
        for attr, value in vars(self).items():
            str_ += f"-【{attr}:{value}】"
        return str_


class TreasuryDepositContract:
    """
        存款合同
        """

    def __init__(self):
        self.amount:float = 0.0

    def __str__(self):
        str_ = '财政（国库）存款'
        for attr, value in vars(self).items():
            str_ += f"-【{attr}:{value}】"
        return str_


class LoanContract:
    """
    贷款合同
    """

    def __init__(self, contract):
        if len(contract) > 0:
            self.bank_id = contract['bank_id']
            self.amount = contract['amount']
            self.interest_rate = contract['interest_rate']
            if 'firm_id' in contract:
                self.firm_id = contract['firm_id']
            if 'household_id' in contract:
                self.household_id = contract['household_id']
            if 'contract_year' in contract:
                self.contract_year = contract['contract_year']
            if 'left_year' in contract:
                self.left_year = contract['left_year']

    def __str__(self):
        str_ = ''
        for attr, value in vars(self).items():
            if isinstance(value, float):
                str_ += f"-【{attr}:{value:.4f}】"
            else:
                str_ += f"-【{attr}:{value}】"
        return str_


class LoanContractCollection:
    def __init__(self, contracts_li: List[LoanContract]):
        self.loan_contracts = contracts_li

    def add_new_loan(self, new_loan: LoanContract):
        self.loan_contracts.insert(0, new_loan)

    def clear_maturing_loan(self):
        clear_idx = []
        for i, loan in enumerate(self.loan_contracts):
            if loan.left_year == 0:
                clear_idx.append(i)
        for i in clear_idx:
            # apt('删除到期贷款', self.loan_contracts[i])
            del self.loan_contracts[i]

    def cal_loans_as_debt(self):
        return np.sum([lc.amount for lc in self.loan_contracts])

    def __str__(self):
        str_ = ''
        for loan in self.loan_contracts:
            str_ += f"{loan.__str__()}\n"
        return str_

    def __iter__(self):
        for item in self.loan_contracts:
            yield item

    def __len__(self):
        return len(self.loan_contracts)

    def __getitem__(self, item):
        return self.loan_contracts[item]


class JobContract:
    """
    劳动力合同
    """

    def __init__(self, contract):
        if len(contract) > 0:
            self.wage = contract['wage']
            self.household_id = contract['household_id']
            self.employer = contract['employer']
            self.employed = contract['employed']
        if 'dole' in contract:
            self.dole = contract['dole']

    def __str__(self):
        str_ = '就业（失业保障）合同'
        for attr, value in vars(self).items():
            str_ += f"-【{attr}:{value}】"
        return str_


class StockHolderContract:
    """
    股份归属
    """

    def __init__(self, contract):
        if len(contract) > 0:
            self.stock_id = contract['stock_id']
            self.stockholder_id = contract['stockholder_id']
            self.share = contract['share']
            self.obj_type = contract['obj_type']

    def __str__(self):
        str_ = '股份持有'
        for attr, value in vars(self).items():
            str_ += f"-【{attr}:{value}】"
        return str_


class BondContract:
    """
    债券合约
    # 默认这种债券是不记名债券，可以流通
    # 发行人必定是政府，也不需要，只需要金额amount，利率interest_rate,发行年份issue_year,债券total_year,剩余年份
    """

    def __init__(self, contract):
        self.amount = contract['amount']
        self.interest_rate = contract['interest_rate']
        self.issue_year = contract['issue_year']
        self.remaining_year = contract['remaining_year']

    def __str__(self):
        str_ = ''
        for attr, value in vars(self).items():
            str_ += f"-【{attr}:{value}】"
        return str_


class CashAdvanceContract:
    """
    现金预借款合约
    """

    def __init__(self, contract):
        self.bank_id = contract['bank_id']
        self.interest_rate = contract['interest_rate']
        self.amount = contract['amount']

    def __str__(self):
        str_ = ''
        for attr, value in vars(self).items():
            str_ += f"-【{attr}:{value}】"
        return str_


class ReserveContract:
    """
        保证金合同
        """

    def __init__(self, contract):
        if len(contract) > 0:
            self.bank_id = contract['bank_id']
            self.amount = contract['amount']

    def __str__(self):
        str_ = ''
        for attr, value in vars(self).items():
            str_ += f"-【{attr}:{value}】"
        return str_
